package com.newviews.tcmip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newviews.tcmip.common.constant.CommonConsts;
import com.newviews.tcmip.common.enums.UiElCodeEnums;
import com.newviews.tcmip.common.model.PageModel;
import com.newviews.tcmip.common.model.ResultModel;
import com.newviews.tcmip.dao.EtcmIngrMapper;
import com.newviews.tcmip.dao.EtcmPxExMapper;
import com.newviews.tcmip.pojo.po.*;
import com.newviews.tcmip.dao.EtcmHerbIngrMapper;
import com.newviews.tcmip.service.inf.EtcmHerbIngrServiceInf;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newviews.tcmip.service.inf.EtcmIngrExServiceInf;
import com.newviews.tcmip.service.inf.EtcmIngrServiceInf;
import com.newviews.tcmip.web.vo.etcmpx.PxIngrStatisticsRespVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 中草药-成分关系表 服务实现类
 * </p>
 *
 * @author lxc
 * @since 2024-03-08
 */
@Service
public class EtcmHerbIngrServiceImpl extends ServiceImpl<EtcmHerbIngrMapper, EtcmHerbIngrPo> implements EtcmHerbIngrServiceInf {
    @Resource
    private EtcmIngrServiceInf etcmIngrServiceInf;
    @Resource
    private EtcmIngrExServiceInf etcmIngrExServiceInf;
    @Resource
    private EtcmIngrMapper etcmIngrMapper;
    @Resource
    private EtcmPxExMapper etcmPxExMapper;


    @Override
    public ResultModel<PageModel<Map<String, String>>> getPageByIngr(String langCode, String uiTypeCode, Integer pageNo, Integer pageSize, String content, String ingrBbb, String ingrCaco2, String ingrHia, String ingrHob, String sortType) {
        uiTypeCode = CommonConsts.UI_TYPE_CODE_INGR;

        if (com.newviews.tcmip.common.utils.StringUtils.isBlank(ingrHia) && com.newviews.tcmip.common.utils.StringUtils.isNotBlank(ingrBbb) && com.newviews.tcmip.common.utils.StringUtils.isNotBlank(ingrCaco2) && com.newviews.tcmip.common.utils.StringUtils.isNotBlank(ingrHob)){
            return new ResultModel<PageModel<Map<String, String>>>().success(new PageModel<>());
        }
        QueryWrapper<EtcmIngrPo> wrapper = new QueryWrapper<>();

        wrapper.eq("t1.status",CommonConsts.COMMON_YES);



        if (StringUtils.isNotBlank(ingrBbb)){
            wrapper.in("t1.ingr_bbb_code",ingrBbb.split(","));
        }
        if (StringUtils.isNotBlank(ingrCaco2)){
            wrapper.in("t1.ingr_caco2_code",ingrCaco2.split(","));
        }
        if (StringUtils.isNotBlank(ingrHia)){
            wrapper.in("t1.ingr_hia_code",ingrHia.split(","));
        }
        if (StringUtils.isNotBlank(ingrHob)){
            wrapper.in("t1.ingr_hob_code",ingrHob.split(","));
        }
        if (StringUtils.isNotBlank(content)){
            wrapper.and(w -> w.like("t1.ingr_zh_name", content)
                    .or().like("t1.ingr_zh_name_abb", content)
                    .or().like("t1.ingr_zh_name_wb", content)
                    .or().like("t1.ingr_zh_name_py", content)
                    .or().like("t1.ingr_en_name", content)
                    .or().like("t1.ingr_en_name_abb", content)
                    .or().like("t1.ingr_latin_name", content)
                    .or().like("t1.ingr_latin_name_abb", content)
                    .or().like("t1.ingr_name_alias", content));
        }
        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            wrapper.orderByAsc("t1.ingr_code");
        }else {
            wrapper.orderByDesc("t1.ingr_code");
        }
        wrapper.groupBy("t1.ingr_code");
        IPage<EtcmIngrPo> page = etcmIngrMapper.getAdmetPageByHerb(new Page<>(pageNo, pageSize),wrapper);

        List<Map<String,String>> resList = new ArrayList<>();
        for (EtcmIngrPo record : page.getRecords()) {
            HashMap<String,String> map = new HashMap<>(16);
            List<EtcmIngrExPo> exList = etcmIngrExServiceInf.list(new QueryWrapper<EtcmIngrExPo>()
                    .eq(EtcmIngrExPo.STATUS, CommonConsts.COMMON_YES)
                    .eq(EtcmIngrExPo.INGR_ID, record.getIngrCode())
                    .eq("language_code",langCode)
                    .eq("ui_type_code",uiTypeCode)
            );

            if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                map.put(UiElCodeEnums.HERB_NAME.getUiElCode(), record.getHerbEnName());
            }
            if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                map.put(UiElCodeEnums.HERB_NAME.getUiElCode(), record.getHerbZhName());
            }
            for (EtcmIngrExPo etcmIngrExPo : exList) {
                map.put(etcmIngrExPo.getUiElCode(),etcmIngrExPo.getIngrExCon());
            }
            resList.add(map);
        }
        PageModel<Map<String,String>> resPage = new PageModel<>();
        resPage.setPageNo(pageNo);
        resPage.setPageSize(pageSize);
        resPage.setRecords(resList);
        resPage.setTotalCount(page.getTotal());
        return new ResultModel<PageModel<Map<String,String>>>().success(resPage);
    }

    @Override
    public ResultModel<PxIngrStatisticsRespVo> getIngredientStatistics(String content, String langCode) {

        QueryWrapper<EtcmIngrPo> wrapper=new QueryWrapper<>();
        if(com.newviews.tcmip.common.utils.StringUtils.isNotBlank(content)){
            wrapper.and(w -> w.like("t2.ingr_zh_name", content)
                    .or().like("t2.ingr_zh_name_py", content)
                    .or().like("t2.ingr_zh_name_wb", content)
                    .or().like("t2.ingr_zh_name_abb", content)
                    .or().like("t2.ingr_en_name", content)
                    .or().like("t2.ingr_en_name_abb", content)
                    .or().like("t2.ingr_latin_name", content)
                    .or().like("t2.ingr_latin_name_abb", content)
                    .or().like("t2.ingr_name_alias", content)
            );
        }

        List<EtcmIngrPo> ingrList = etcmIngrServiceInf.list(wrapper);
        Map<String, Long> ingrBbbMap = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrBbbCode())).collect(Collectors.groupingBy(EtcmIngrPo::getIngrBbbCode, Collectors.counting()));
        long ingrBbbCount = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrBbbCode())).count();
        Map<String, Long> ingrCaco2Map = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrCaco2Code())).collect(Collectors.groupingBy(EtcmIngrPo::getIngrCaco2Code, Collectors.counting()));
        long ingrCaco2Count = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrCaco2Code())).count();
        Map<String, Long> ingrHiaMap = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrHiaCode())).collect(Collectors.groupingBy(EtcmIngrPo::getIngrHiaCode, Collectors.counting()));
        long ingrHiaCount = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrHiaCode())).count();
        Map<String, Long> ingrHobMap = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrHobCode())).collect(Collectors.groupingBy(EtcmIngrPo::getIngrHobCode, Collectors.counting()));
        long ingrHobCount = ingrList.stream().filter(etcmIngrPo -> com.newviews.tcmip.common.utils.StringUtils.isNotBlank(etcmIngrPo.getIngrHobCode())).count();
        List<String> ingrBbbList = getIngrStatistics(ingrBbbCount, ingrBbbMap);
        List<String> ingrCaco2List = getIngrStatistics(ingrCaco2Count, ingrCaco2Map);
        List<String> ingrHiaList = getIngrStatistics(ingrHiaCount, ingrHiaMap);
        List<String> ingrHobList = getIngrStatistics(ingrHobCount, ingrHobMap);
        PxIngrStatisticsRespVo vo = new PxIngrStatisticsRespVo();
        vo.setIngrBbb(ingrBbbList);
        vo.setIngrCaco2(ingrCaco2List);
        vo.setIngrHia(ingrHiaList);
        vo.setIngrHob(ingrHobList);
        return new ResultModel<PxIngrStatisticsRespVo>().success(vo);

    }

    @Override
    public List<Map<String, String>> downloadAdmet(String ingrHia, String ingrHob, String ingrBbb, String ingrCaco2, String uiTypeCode, String langCode, String sortType,String content) {
        uiTypeCode = CommonConsts.UI_TYPE_CODE_INGR;
        if (com.newviews.tcmip.common.utils.StringUtils.isBlank(ingrHia) && com.newviews.tcmip.common.utils.StringUtils.isNotBlank(ingrBbb) && com.newviews.tcmip.common.utils.StringUtils.isNotBlank(ingrCaco2) && com.newviews.tcmip.common.utils.StringUtils.isNotBlank(ingrHob)){
            return new ArrayList<>();
        }
        QueryWrapper<EtcmHerbExPo> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(content)){
            wrapper.and(w->w.like( "t1.ingr_zh_name", content)
                    .or().like( "t1.ingr_zh_name_py", content)
                    .or().like( "t1.ingr_zh_name_wb",content)
                    .or().like( "t1.ingr_zh_name_abb", content)
                    .or().like( "t1.ingr_en_name", content)
                    .or().like( "t1.ingr_en_name_abb", content)
                    .or().like( "t1.ingr_latin_name", content)
                    .or().like( "t1.ingr_latin_name_abb", content)
                    .or().like( "t1.ingr_name_alias", content)
            );
        }

        wrapper.eq("t1.status", CommonConsts.COMMON_YES);



        if(sortType.equalsIgnoreCase(CommonConsts.SORT_TYPE_ASC)){
            wrapper.orderByAsc("t1.ingr_code");
        }else {
            wrapper.orderByDesc("t1.ingr_code");
        }
        wrapper.groupBy("t1.ingr_code,t4.ingr_id,t4.ui_el_code,t4.ingr_ex_con");
        List<EtcmIngrExPo> page = etcmIngrMapper.downloadAdmet(wrapper,uiTypeCode,langCode);


        // List<Map<String,String>> resList = new ArrayList<>();
        Map<String,List<EtcmIngrExPo>> disMap = new LinkedHashMap<>(16);
        for (EtcmIngrExPo record : page) {
            List<EtcmIngrExPo> disList = new ArrayList<>();

            String[] uiElCodeList = record.getUiElCode().split("\\|\\|");
            String[] herbExConList = record.getIngrExCon().split("\\|\\|");
            for (int i = 0; i < uiElCodeList.length; i++) {
                EtcmIngrExPo etcmHerbExPo = new EtcmIngrExPo();

                for (int j = 0; j < herbExConList.length; j++) {
                    if (i == j){
                        etcmHerbExPo.setUiElCode(uiElCodeList[i]);
                        etcmHerbExPo.setIngrExCon(herbExConList[j]);
                        etcmHerbExPo.setHerbEnName(record.getHerbEnName());
                        etcmHerbExPo.setHerbZhName(record.getHerbZhName());
                    }
                }
                disList.add(etcmHerbExPo);
            }

            disMap.put(record.getIngrId(),disList);
        }


        List<EtcmUiElPo> etcmUiElPos = etcmPxExMapper.getUIElName(uiTypeCode,langCode);
        etcmUiElPos = etcmUiElPos.stream().filter(s -> s.getUiElSort() < 3 || (s.getUiElSort() > 6  && s.getUiElSort() < 12)).sorted(Comparator.comparing(EtcmUiElPo::getUiElSort)).collect(Collectors.toList());
        List<Map<String, String>> resultList = new ArrayList<>();

        for (String key : disMap.keySet()) {
            Map<String,String> mapRes=new HashMap<>(16);
            List<EtcmIngrExPo> values = disMap.get(key);
            List<String> collect = values.stream().map(EtcmIngrExPo::getUiElCode).collect(Collectors.toList());
            for (EtcmUiElPo etcmUiElPo : etcmUiElPos) {
                if (collect.contains(etcmUiElPo.getUiElCode())){
                    for (EtcmIngrExPo etcmHerbExPo : values) {
                        if (etcmUiElPo.getUiElCode().equals(etcmHerbExPo.getUiElCode())){
                            mapRes.put(etcmHerbExPo.getUiElCode(), etcmHerbExPo.getIngrExCon());
                            if (CommonConsts.LANG_CODE_ENG.equals(langCode)){
                                mapRes.put(UiElCodeEnums.HERB_NAME.getUiElCode(), etcmHerbExPo.getHerbEnName());
                            }
                            if (CommonConsts.LANG_CODE_CHN.equals(langCode)){
                                mapRes.put(UiElCodeEnums.HERB_NAME.getUiElCode(), etcmHerbExPo.getHerbZhName());
                            }
                        }
                    }
                }else {
                    mapRes.put(etcmUiElPo.getUiElCode(), "");
                }

            }

            resultList.add(mapRes);
        }

        return resultList;
    }

    private List<String> getIngrStatistics(Long totalNumber, Map<String, Long> map) {
        List<String> arr = new ArrayList<>();
        for (String key : map.keySet()) {

            BigDecimal totalSize = new BigDecimal(totalNumber);
            BigDecimal size = new BigDecimal(map.get(key));
            BigDecimal bigDecimal = size.divide(totalSize,2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            arr.add(bigDecimal.toString());
        }
        return arr;
    }
}
